import { useEffect, useState, useMemo } from 'react';
import dayjs from 'dayjs';
import usePersistFn from './usePersistFn';

export type TDate = Date | number | string | undefined;

export type Options = {
  targetDate?: TDate;
  interval?: number;
  onEnd?: () => void;
};

export interface FormattedRes {
  days: number;
  hours: number;
  minutes: number;
  seconds: number;
  milliseconds: number;
}

const parseMs = (milliseconds: number): FormattedRes => {
  return {
    days: Math.floor(milliseconds / (1000 * 60 * 60 * 24)),
    hours: Math.floor(milliseconds / (1000 * 60 * 60)) % 24,
    minutes: Math.floor(milliseconds / (1000 * 60)) % 60,
    seconds: Math.floor(milliseconds / 1000) % 60,
    milliseconds: Math.floor(milliseconds) % 1000,
  };
};

const calcLeft = (t?: TDate) => {
  if (!t) {
    return 0;
  }

  let left = dayjs(t).valueOf() - new Date().getTime();

  if (left < 0) {
    return 0;
  }

  return left;
};

const useCountdown = (options?: Options) => {
  const {
    targetDate, // 未来时间 Date | undefined
    interval = 1000, // 变化时间间隔（毫秒）
    onEnd, // 未来时间结束后的回调 Function | undefined
  } = options || {};

  const [target, setTarget] = useState<TDate>(targetDate);
  const [timeLeft, setTimeLeft] = useState(() => calcLeft(target));

  const onEndPersistFn = usePersistFn(() => {
    onEnd && onEnd();
  });

  useEffect(() => {
    if (!target) {
      // for stop
      setTimeLeft(0);
      return;
    }

    // 立即执行一次
    setTimeLeft(calcLeft(target));

    let timer = setInterval(() => {
      let targetLeft = calcLeft(target);
      setTimeLeft(targetLeft);

      if (targetLeft === 0) {
        clearInterval(timer);
        onEndPersistFn();
      }
    }, interval);

    return () => {
      clearInterval(timer);
    };
  }, [target, interval]);

  const formattedRes = useMemo(() => {
    return parseMs(timeLeft);
  }, [timeLeft]);

  return [timeLeft, setTarget, formattedRes] as const;
};

// 用法
// const [countdown, setTargetDate, formattedRes] = useCountDown({
//   targetDate,
//   interval,
//   onEnd,
// });

export default useCountdown;
